#ifndef __UNROLL_TEMPLATE_INL__
#define __UNROLL_TEMPLATE_INL__

template<int M, int N>
struct lp_add_4{
	inline static void run(const int pNumPass, ATYP(M) &lhs, const_ATYP(N) &rhs, std::bitset<M>& ovfw_flag, std::bitset<M>& flbt_flag){
		const int idx = pNumPass<<2;
		
// 		__declspec(align(16)) UINT32 ovfw_buffer[4];
		__declspec(align(16)) UINT32 flbt_buffer[4]={0,0,0,0};
		
		SSE_OPS::add_4_uint32_sse_carry(&lhs[idx],&rhs[idx],&lhs[idx],flbt_buffer);
		
// 		ovfw_flag[idx  ] = (ovfw_buffer[0]&0x80000000)?true:false;
// 		ovfw_flag[idx+1] = (ovfw_buffer[1]&0x80000000)?true:false;
// 		ovfw_flag[idx+2] = (ovfw_buffer[2]&0x80000000)?true:false;
// 		ovfw_flag[idx+3] = (ovfw_buffer[3]&0x80000000)?true:false;
// 
// 		flbt_flag[idx  ] = (flbt_buffer[0]&0x80000000)?true:false;
// 		flbt_flag[idx+1] = (flbt_buffer[1]&0x80000000)?true:false;
// 		flbt_flag[idx+2] = (flbt_buffer[2]&0x80000000)?true:false;
// 		flbt_flag[idx+3] = (flbt_buffer[3]&0x80000000)?true:false;
	}
};

template<int M, int N>
struct lp_add_4_2{
	inline static void run(const int pNumPass, ATYP(M) &lhs, const std::bitset<M>& flags){
		if (flags[pNumPass])
		{
			++lhs[pNumPass];
		}
	}
};

template<int M, int N>
struct lp_sub_4{
	inline static void run(const int pNumPass, ATYP(M) &lhs, const_ATYP(N) &rhs){
		const int idx = pNumPass<<2;
		SSE_OPS::sub_4_uint32(&lhs[idx],&rhs[idx],&lhs[idx]);
	}
};

template<int M, int N>
struct lp_sub_4_2{
	inline static void run(const int pNumPass, ATYP(M) &lhs, const std::bitset<M>& flags){
		if (flags[pNumPass])
		{
			--lhs[pNumPass];
		}
	}
};

template<typename ExeT, typename T0, typename T1>
struct UnrollLoop_2Params {
	template<int N>
	struct Loop {
		inline static void pass(T0 p0, T1 p1)
		{
			ExeT::run(N,p0,p1);
			Loop<N-1>::pass(p0,p1);
		}
	};

	template<>
	struct Loop<0> {
		inline static void pass(T0 p0, T1 p1)
		{
			ExeT::run(0,p0,p1);
		}
	};
};

template<typename ExeT, typename T0, typename T1, typename T2, typename T3>
struct UnrollLoop_4Params {
	template<int N>
	struct Loop {
		inline static void pass(T0 p0, T1 p1, T2 p2, T3 p3)
		{
			ExeT::run(N,p0,p1,p2,p3);
			Loop<N-1>::pass(p0,p1,p2,p3);
		}
	};

	template<>
	struct Loop<0> {
		inline static void pass(T0 p0, T1 p1, T2 p2, T3 p3)
		{
			ExeT::run(0,p0,p1,p2,p3);
		}
	};
};



#endif